/**
 * @class   wosh::MethodT
 * @brief   Holds generic method information, required arguments and its
 *          (imlementation) pointer.
 *
 *
 *
 *
 *
Casting between member function pointers is an extremely murky area. During the standardization of C++, there was a lot of discussion about whether you should be able to cast a member function pointer from one class to a member function pointer of a base or derived class, and whether you could cast between unrelated classes. By the time the standards committee made up their mind, different compiler vendors had already made implementation decisions which had locked them into different answers to these questions. According to the Standard (section 5.2.10/9), you can use reinterpret_cast  to store a member function for one class inside a member function pointer for an unrelated class. The result of invoking the casted member function is undefined. The only thing you can do with it is cast it back to the class that it came from. I'll discuss this at length later in the article, because it's an area where the Standard bears little resemblance to real compilers.


VARIANT consente di fare un MethodT generico
vedi
http://www.codeguru.com/cpp/w-p/dll/article.php/c3645


 *
 *
 *
 *
 ****************************************************************************
 * @version $Id: MethodT.h 2778 2010-07-18 18:29:37Z alex $
 * @author  Alessandro Polo
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR MethodTS;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/

#ifndef __WOSH_Core_MethodT_H__
 #define __WOSH_Core_MethodT_H__

 #include <woshDefs.h>
 #include <core/Method.h>

#ifdef _ENABLE_PROFILING
 #include <core/SystemProfiler.h>
#endif

namespace wosh {


template <typename ARG_TYPE, class RUNNER_TYPE, typename RET_TYPE>
class MethodT : public Method
 {
	WOSH_CLASSNAME(wosh::MethodT)
	WOSH_CLASS_ABSTRACT(true)

	typedef RET_TYPE (RUNNER_TYPE::*MethodTPtr)(const ARG_TYPE argument);


	public:
		MethodT( const std::string& Name )
			: Method(Name) {
			this->smMethodTPointer = NULL;
			this->parent = NULL;
		 }

		MethodT( const std::string& Name, const std::string& Description, const Permission& Perm = Permission::R_XR_XR__() )
			: Method(Name, Description, Perm ) {
			this->smMethodTPointer = NULL;
			this->parent = NULL;
		 }

		virtual ~MethodT() { }

/** @name Execution and Validation
 * @{
 ******************************************************************************/
	public:
		virtual Message* exec( const Message* request ) = 0;

		//wrapper to member function pointer
		RET_TYPE execT( const ARG_TYPE argument ) {
			if ( this->parent == NULL || this->smMethodTPointer == NULL )
				return NULL;

			PROFILING_ENTER(this, 0)
			RET_TYPE temp = (this->parent->*smMethodTPointer)(argument);
			PROFILING_EXIT(this, 0)
			return temp;
		 }

//@}
/** @name Setters
 * @{
 ******************************************************************************/
	public:
		// set member function pointer: (MethodTPtr)&SomeClass::some_member_func
		virtual void setMethod( RUNNER_TYPE* pare, MethodTPtr fptr ) {
			this->parent = pare;
			this->smMethodTPointer = fptr;
			PROFILING_INIT(this, this->parent);
		 }
//@}
/** @name Getters
 * @{
 ******************************************************************************/
	public:
		virtual bool isLinkedFunction() const		{ return (this->smMethodTPointer != NULL); }
		virtual bool isLinkedParent() const			{ return (this->parent != NULL); }
//@}
	protected:
		RUNNER_TYPE* parent;			///< parent of the method (usually it's the object implementing it)
		MethodTPtr smMethodTPointer;	///< real function pointer

		virtual void clear() {
			Method::clear();
			this->smMethodTPointer = NULL;
			this->parent = NULL;
		 }

}; // class def

}; // namespace wosh

#endif //__WOSH_Core_MethodT_H__
